#include "BlockQueue.hpp"
#include "Task.hpp"
#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <functional>

using namespace BlockQueueModule;
using namespace TaskModule;
void Flush()
{
    std::cout << "我是内核缓冲区刷新任务" << std::endl;
}
void Log()
{
    std::cout << "我是打印日志任务" << std::endl;
}
using func_t = std::function<void(void)>;

void *Consumer(void *args)
{
    BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args);

    //BlockQueue<func_t> *bq = static_cast<BlockQueue<func_t> *>(args);
    while(true)
    {
        //sleep(1);
        // func_t task;
        Task t;
        // 1. 从bq拿到数据
        // bq->pop(&task);
        bq->pop(&t);
        t.Excute();
        // task();

        printf("Consumer, 处理完成一个任务: %d+%d=%d\n", t.X(), t.Y(), t.Result());
        printf("Consumer, 消费了一个数据\n");
    }
}

void *Productor(void *args)
{
    BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args);

    // BlockQueue<func_t> *bq = static_cast<BlockQueue<func_t> *>(args);
    int data = 10;
    while (true)
    {
        sleep(2);
        // data = 10; 

        int x = rand() % 10 + 1; // [1, 10]
        int y = rand() % 20 + 1; // [1, 20]
        Task t(x, y); // 构建任务

        // bq->Enqueue(Flush);
        bq->Enqueue(t);

        printf("producter 生产了一个数据\n");
        // printf("producter 生产了一个任务: %d+%d=?\n", t.X(), t.Y());
        data++;
    }
}
int main()
{
    BlockQueue<func_t> *bq = new BlockQueue<func_t>(5); 
    // 单生产，单消费
    pthread_t c1, p1;
    //多生产多消费  
    //pthread_t c1,c2,p1,p2,p3;

    pthread_create(&c1, nullptr, Consumer, bq);
    // pthread_create(&c2, nullptr, Consumer, bq);
    pthread_create(&p1, nullptr, Productor, bq);
    // pthread_create(&p2, nullptr, Productor, bq);
    // pthread_create(&p3, nullptr, Productor, bq);    

    pthread_join(c1, nullptr);
    // pthread_join(c2, nullptr);
    pthread_join(p1, nullptr);
    // pthread_join(p2, nullptr);
    // pthread_join(p3, nullptr);

    delete bq;
    return 0;
}